package com.syf.model;

import com.syf.domain.DepthItemVo;
import com.syf.enums.OrderDirection;
import lombok.Data;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.LinkedList;

/**
 * 交易的 盘口数据【挂单：显示还有多少委托单可以 买入/卖出】：  完成的委托单 则需要从盘口中删除
 *      以后前端可以查询该数据
 *
 *      若委托单交易数量完成，则不会出现在盘口；
 *      只有购买后还没交易足够的委托单才会出现在盘口(我需要20个，但我只完成了16，还有四个没买够，就挂载到盘口)
 */
@Data
public class TradePlate {


    /**
     * 盘口数据的初始化--判断数据的详情
     */
    private LinkedList<DepthItemVo> items = new LinkedList<DepthItemVo>();

    /**
     * 最大支持的深度【最多显示多少条记录】
     */
    private int maxDepth = 100;

    /**
     * 订单的方向【买入/卖出】
     */
    private OrderDirection direction;

    /**
     * 交易对
     */
    private String symbol;

    public TradePlate(String symbol, OrderDirection direction) {
        this.symbol = symbol;
        this.direction = direction;
    }


    /**
     * 添加订单数据到盘口数据里面
     *      当我们新增一个委托单时: 它没有全部的成交 ,因此把它展示在盘口里面
     *      你给的价格14块，大于14元的直接跳过，等于14的直接增加挂单数量，指定链表i位置插入一条挂单数据
     * @param order
     */
    public void add(Order order) {
        if (order.getOrderDirection() != direction) {
            return;
        }
        int i = 0;
        for (i = 0; i < items.size(); i++) {
            // 1 我们的sell 队列是: 从小到大【别人想低价买入】
            // 2 我们的buy 队列是: 从大到小【我想高价卖出】
            DepthItemVo depthItemVo = items.get(i);
            if (   //买入：别人出售价格太高-买不起， 卖出：别人给的价格太低-卖了不赚钱
                    (direction == OrderDirection.BUY && order.getPrice().compareTo(depthItemVo.getPrice()) == -1)
                            ||
                    (direction == OrderDirection.SELL && order.getPrice().compareTo(depthItemVo.getPrice()) == 1)
        ) {
                // 还不能插入,往前走一步
                continue; //跳过本次循环体中余下尚未执行的语句，立即进行下一次的循环条件

            } else if (depthItemVo.getPrice().compareTo(order.getPrice()) == 0) {  //我想花10元买，恰好你也10元出售
                //挂单委托量 + 当前还剩下委托单数量没交易完【该价格的所有挂单 数量】
                depthItemVo.setVolume(depthItemVo.getVolume().add(order.getAmount().subtract(order.getTradedAmount())));
                return;  //return后整个方法结束包括里面的for循环也终止了，后面不再执行

            } else { //没有该价格的委托单挂单，添加一个
                break; // 我就想插入 当前我就在第 i --》得到当前i位置
            }
        }

        //没有该价格的委托单挂单，添加一个
        if (i < maxDepth) {  //最多显示100条挂单记录
            DepthItemVo depthItemVo = new DepthItemVo();
            depthItemVo.setPrice(order.getPrice());
            depthItemVo.setVolume(order.getAmount().subtract(order.getTradedAmount())); //还剩5个没卖出
            //LinkList 按插入数据的大小自带排序,  在指定下标i出插入，原本的数据全部往后移动
            items.add(i, depthItemVo);  //盘口数据添加 剩余数量挂单 【有该价格的委托单挂单，添加一个】
        }
    }

    public static void main(String[] args) {
        LinkedList<DepthItemVo> items = new LinkedList<DepthItemVo>();
        items.add(0,new DepthItemVo(new BigDecimal(13),new BigDecimal(12)));
        items.add(1,new DepthItemVo(new BigDecimal(12),new BigDecimal(13)));
        items.add(2,new DepthItemVo(new BigDecimal(14),new BigDecimal(14)));
        items.add(3,new DepthItemVo(new BigDecimal(13),new BigDecimal(13)));
        items.add(4,new DepthItemVo(new BigDecimal(13),new BigDecimal(13)));
        items.add(0,new DepthItemVo(new BigDecimal(12.5),new BigDecimal(12.5)));

        items.forEach(item -> {
            System.out.println(item.getPrice()+ "---" + item.getVolume());
        });
        System.out.println("数量：" + items.size());
    }





    /**
     * 从盘口里面移除订单(下架委托订单：将剩余的直接下架)
     *
     * @param order
     */
    public void remove(Order order) {
        //order.getAmount().subtract(order.getTradedAmount())  需要20个，可能已经买了16个，还需要4个
        remove(order, order.getAmount().subtract(order.getTradedAmount()));
    }

    /***
     * 从盘口里面移除--成交的数据
     * @param order
     * @param amount
     */
    public void remove(Order order, BigDecimal amount) { //订单、成交量

        if (items.size() == 0) {
            return;
        }
        if (order.getOrderDirection() != direction) {  //交易方向不同
            return;
        }
        Iterator<DepthItemVo> iterator = items.iterator();
        while (iterator.hasNext()) {
            DepthItemVo next = iterator.next();
            if (order.getPrice().compareTo(next.getPrice()) == 0) { // 价格相同
                next.setVolume(next.getVolume().subtract(amount));  //委托量
                if (next.getVolume().compareTo(BigDecimal.ZERO) <= 0) {
                    iterator.remove(); // 若委托量为 0 后,我们直接可以摘掉它
                }
            }

        }

    }


}
